package cn.gailvlun.gll.presentation.xroom

import android.app.Dialog
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.SimpleItemAnimator
import android.view.View
import android.widget.EditText
import cn.gailvlun.gll.R
import cn.gailvlun.gll.bean.PlaceHolder
import cn.gailvlun.gll.chatkit.message.MessageInput
import cn.gailvlun.gll.chatlib.ChatClient2
import cn.gailvlun.gll.chatlib.event.CrossMessageEvent
import cn.gailvlun.gll.chatlib.event.CrossStatus
import cn.gailvlun.gll.chatlib.event.CrossStatusEvent
import cn.gailvlun.gll.mgr.UploadMgr
import cn.gailvlun.gll.mgr.UploadResult
import cn.gailvlun.gll.net.HttpMethods
import cn.gailvlun.gll.net.HttpSubscriber
import cn.gailvlun.gll.net.base.friend.AddFriendReq
import cn.gailvlun.gll.net.base.friend.FriendNotification
import cn.gailvlun.gll.net.cross.LeaveRoomReq
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.xroom.adapter.*
import cn.gailvlun.gll.presentation.xroom.vm.CrossRoomChatViewModel
import cn.gailvlun.gll.util.*
import cn.gailvlun.gll.widget.OnCancelListener
import cn.gailvlun.gll.widget.OnConfirmListener
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.SpanUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
import io.reactivex.Observer
import io.reactivex.SingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.activity_cross_room_chat.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.util.*

fun Int.length(): Int {
    return toString().length
}

class CrossRoomChatActivity : BaseActivity() {

    companion object {
        fun openActivity(context: Context, oppositeId: Int, gameId: Int) {
            val intent = Intent(context, CrossRoomChatActivity::class.java)
            intent.putExtra("oppositeId", oppositeId)
            intent.putExtra("gameId", gameId)
            context.startActivity(intent)
        }
    }

    private var mViewModel: CrossRoomChatViewModel? = null
    private var mAdapter: CrossRoomChatAdapter? = null
    private var mLayoutManager: LinearLayoutManager? = null

    override fun initComponent() {
        setContentView(R.layout.activity_cross_room_chat)

        val oppositeId = intent.getIntExtra("oppositeId", -1)
        val gameId = intent.getIntExtra("gameId", -1)
        oppositeId.apply {
            if (this == -1 || gameId == -1)
                finish()
        }

        mViewModel = ViewModelProviders.of(this).get(CrossRoomChatViewModel::class.java)
        mViewModel?.init(gameId)
        mViewModel?.oppositeId = oppositeId

        nbv.setTitleText(mViewModel?.getOppositeName())

        rv.itemAnimator.changeDuration = 0
        (rv.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false

        mAdapter = CrossRoomChatAdapter(mContext)
        rv.adapter = mAdapter

        mLayoutManager = LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, true)
        mAdapter?.mLayoutManager = mLayoutManager

        mLayoutManager?.stackFromEnd = true
        rv.layoutManager = mLayoutManager

        Glide.with(mContext)
                .load(R.drawable.img_cross_room_introduce)
                .into(object: SimpleTarget<Drawable>() {
                    override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
                        ll_bg.setBackgroundDrawable(resource)
                    }
                })
    }

    override fun onBackPressed() {
        LeftDialog(mContext)
                .apply {
                    onConfirmListener = object : OnConfirmListener<Any> {
                        override fun onConfirm(dialog: Dialog, data: Any?) {
                            dismiss()
                        }
                    }
                    onCancelListener = object : OnCancelListener<Any> {
                        override fun onCancel(dialog: Dialog, data: Any?) {
                            leaveRoom()
                        }
                    }
                }
                .show()
    }

    private fun leaveRoom() {
        HttpMethods.getCrossService()
                .leaveRoom(LeaveRoomReq(mViewModel?.crossRoomInfo?.id!!))
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<PlaceHolder>() {
                    override fun onSuccess(response: PlaceHolder?) {
                        super@CrossRoomChatActivity.onBackPressed()
                    }

                    override fun onFailure(errMsg: String?, response: PlaceHolder?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                    }
                })
    }

    override fun createHandler() {
        nbv.setOnBackListener {
            onBackPressed()
        }

        cmi.onSubmitListener = object: MessageInput.OnSubmitListener {
            override fun onSubmit(etInput: EditText) {
                if (!IsEmpty.string(etInput.text.toString())) {
                    
                    
                    if (StringUtil.isAllSpace(etInput.text.toString())) {
                        ToastUtil.showShort("不能发送空白消息")
                        etInput.text = null
                        return
                    }

                    var crossMessage = mViewModel!!.getMessage(etInput.text.toString())
                    if (ChatClient2.getInstance().sendCrossMessage(crossMessage)) {
                        mViewModel?.save(crossMessage)
                        mAdapter?.addLatest(crossMessage)
                        etInput.text = null
                    }
                }
            }

        }

        cmi.onPictureSuccessListener = object:  MessageInput.OnPictureSuccessListener {
            override fun onPictureSuccess(pictureFile: File, width: Int, height: Int) {
                var theWidth = width
                var theHeight = height
                if (width == 0 || height == 0) {
                    val size = ImageUtil.getImageWidthHeight(pictureFile.path)
                    theWidth = size[0]
                    theHeight = size[1]
                }

                val imgMsg = mViewModel?.getImageMessage(pictureFile.absolutePath, theWidth, theHeight)
                mAdapter?.addLatest(imgMsg!!)
                mViewModel?.save(imgMsg!!)

                
                val objectKey = UUID.randomUUID().toString() + '.'.toString() + FileUtils.getFileExtension(pictureFile)

                
                UploadMgr.getInstance().upload(objectKey, pictureFile.path)
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(object : SingleObserver<UploadResult<PutObjectRequest, PutObjectResult>> {
                            override fun onSubscribe(d: Disposable) {}

                            override fun onSuccess(result: UploadResult<PutObjectRequest, PutObjectResult>) {
                                imgMsg?.image = result.request.objectKey
                                if (ChatClient2.getInstance().sendCrossMessage(imgMsg)) {
                                    imgMsg?.image = "https://img.xiaogaijun.com/" + imgMsg?.image
                                }
                            }

                            override fun onError(e: Throwable) {}
                        })
            }
        }
    }

    override fun loadData(savedInstanceState: Bundle?) {
        ToastUtil.showCenter(SpanUtils().append("试聊将在")
                .append("${mViewModel?.crossRoomInfo?.beforeOpenTime}").setForegroundColor(mContext.resources.getColor(R.color.apricot))
                .appendLine("秒后开始")
                .append("第一轮对话将由")
                .append(mViewModel?.crossRoomInfo?.first?.owner?.name!!).setForegroundColor(mContext.resources.getColor(R.color.apricot))
                .append("发起")
                .create())

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onCrossStatusEvent(event: CrossStatusEvent) {
        changeStatus(event.status, event.description)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onReceiveMessage(event: CrossMessageEvent) {
        if (event.oppositeId == mViewModel?.oppositeId) {
            mAdapter?.addLatest(mViewModel?.getCrossMessage(event.messageId))
        }
    }

    private var crossStatus: CrossStatus? = null
    private fun changeStatus(crossStatus: CrossStatus, description: String?) {
        if (crossStatus == crossStatus) {
            return
        }
        when (crossStatus) {
            CrossStatus.FIRST_RIDDLE -> {
                riddleInit(0)
            }
            CrossStatus.FIRST_RIDDLE_ANSWER -> {
                riddleAnswerInit(0)
            }
            CrossStatus.FIRST_PUNISH -> {
                punishInit(0)
            }
            CrossStatus.HALF_TIME -> {
                halfTime()
            }
            CrossStatus.SECOND_RIDDLE -> {
                riddleInit(1)
            }
            CrossStatus.SECOND_RIDDLE_ANSWER -> {
                riddleAnswerInit(1)
            }
            CrossStatus.SECOND_PUNISH -> {
                punishInit(1)
            }
            CrossStatus.COMMENTING -> {
                commenting()
            }
            CrossStatus.COMMENTED -> {
                commented(description)
            }
            CrossStatus.OTHER_EXIT -> {
                friendExit()
            }
        }
        this.crossStatus = crossStatus
    }



    private fun riddleInit(round: Int) {
        cdv.visibility = View.VISIBLE
        RxUtil.countDown(mViewModel?.crossRoomInfo?.riddleTime?.toLong()!!)
                .subscribe(object : Observer<Long> {
                    override fun onComplete() {
                        cdv.toggle()
                        cdv.visibility = View.INVISIBLE
                    }

                    override fun onSubscribe(d: Disposable) {
                    }

                    override fun onNext(t: Long) {
                        cdv.setText(t.toInt())
                    }

                    override fun onError(e: Throwable) {
                    }
                })
        RxUtil.timer(mViewModel?.crossRoomInfo?.let {
            return@let it.riddleTime - it.riddleCountDownTime
        }?.toLong()!!)
                .subscribe {
                    
                    cdv.toggle()
                }

        
        mAdapter?.addLatest(mViewModel!!.saveRiddle(round))

        
        mAdapter?.addLatest(mViewModel!!.saveAnswerStartSystemMsg(round))
    }

    private fun riddleAnswerInit(round: Int) {
        mAdapter?.addLatest(mViewModel!!.saveAnswerDoneSystemMsg(round))

        if (mViewModel?.isAnswerManBy(round)!!) {
            InputAnswerDialog(mContext, round == 0, mViewModel?.crossRoomInfo?.id!!, mViewModel?.crossRoomInfo?.riddleAnswerTime!!)
                    .show()
        }
    }

    private fun punishInit(round: Int) {
        mAdapter?.addLatest(mViewModel!!.saveAnswerResultSystemMsg(round))

        cdv.visibility = View.VISIBLE
        RxUtil.countDown(mViewModel?.crossRoomInfo?.punishTime?.toLong()!!)
                .subscribe(object : Observer<Long> {
                    override fun onComplete() {
                        cdv.toggle()
                        cdv.visibility = View.INVISIBLE
                    }

                    override fun onSubscribe(d: Disposable) {
                    }

                    override fun onNext(t: Long) {
                        cdv.setText(t.toInt())
                    }

                    override fun onError(e: Throwable) {
                    }
                })

        RxUtil.timer(mViewModel?.crossRoomInfo?.let {
            return@let it.punishTime - it.punishCountDownTime
        }?.toLong()!!)
                .subscribe {
                    

                    cdv.toggle()
                }
    }

    private fun halfTime() {
        ToastUtil.showCenter(SpanUtils()
                .appendLine("惩罚环节时间到！\n即将进入第二轮试聊")
                .append("本轮对话将由")
                .append("${mViewModel?.crossRoomInfo?.second?.owner?.name}").setForegroundColor(mContext.resources.getColor(R.color.apricot))
                .appendLine("发起")
                .append("倒计时")
                .append("${mViewModel?.crossRoomInfo?.halfTime}").setForegroundColor(mContext.resources.getColor(R.color.apricot))
                .append("秒")
                .create())



    }

    private fun commenting() {
        GameEndDialog(mContext, mViewModel?.crossRoomInfo?.commentingTime!!,
                mViewModel?.crossRoomInfo?.isFirst!!,
                mViewModel?.crossRoomInfo?.id!!)
                .show()
    }

    private fun commented(description: String?) {
        if (description == null || description.isEmpty()) {
            NoCommentDialog(mContext)
                    .apply {
                        onConfirmListener = object : OnConfirmListener<Any> {
                            override fun onConfirm(dialog: Dialog, data: Any?) {
                                addFriend()
                            }
                        }
                        onCancelListener = object : OnCancelListener<Any> {
                            override fun onCancel(dialog: Dialog, data: Any?) {
                                dialog.dismiss()
                                finish()
                            }
                        }
                    }
                    .show()
        } else {
            ImpressionDialog(mContext, description)
                    .apply {
                        onConfirmListener = object : OnConfirmListener<Any> {
                            override fun onConfirm(dialog: Dialog, data: Any?) {
                                addFriend()
                            }
                        }
                        onCancelListener = object : OnCancelListener<Any> {
                            override fun onCancel(dialog: Dialog, data: Any?) {
                                dialog.dismiss()
                                finish()
                            }
                        }
                    }
                    .show()
        }
    }

    private fun addFriend() {
        val pd = DialogUtil.showIndeterminate(mContext)
        HttpMethods.getFriendService()
                .addFriend(AddFriendReq(mViewModel?.oppositeId!!))
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<FriendNotification>() {
                    override fun onSuccess(response: FriendNotification?) {
                        ToastUtil.showShort("请求已提交，请等待对方同意哦\n" +
                                "3s后页面将自动跳转")
                        RxUtil.timer(3)
                                .subscribe {
                                    finish()
                                }
                    }

                    override fun onFailure(errMsg: String?, response: FriendNotification?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                    }

                    override fun onFinish() {
                        super.onFinish()
                        pd.dismiss()
                    }
                })
    }

    private fun friendExit() {
        FriendExitDialog(mContext)
                .apply {
                    
                    onConfirmListener = object : OnConfirmListener<Any> {
                        override fun onConfirm(dialog: Dialog, data: Any?) {
                            CrossRoomGameInfoActivity.openActivity(mContext)
                            finish()
                        }
                    }
                    
                    onCancelListener = object : OnCancelListener<Any> {
                        override fun onCancel(dialog: Dialog, data: Any?) {
                            finish()
                        }
                    }
                }
                .show()
    }

}